package org.zjt.i18n;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.spi.ResourceBundleControlProvider;

/**
 * @author juntao.zhang
 * @version V1.0
 * @Description: Properties、I18N 转码
 * @Package org.zjt.i18n
 * @date 2018/6/17 19:18
 *
 * jdk format 都是线程不安全的
 *
 * 配置：
 *      -Duser.language=UK   【格式 -Dname=value】
 *
 * {@since 1.6} control
 * {@since 1.8} provider control  spi
 *
 * {@link PropertyResourceBundle}
 * {@link ResourceBundleControlProvider}
 * {@link ResourceBundle}
 *
 *
 * control提供了默认的编码、解码器。ResourceBundleControlProvider 为编码提供者。SPI
 *
 * 会优先从 SPI 的 service {@link ResourceBundle#getDefaultControl(java.lang.String)} 中得到{@link ResourceBundleControlProvider}。如果没有SPI实现，
 * 就是用默认的 ResourceBundleControlProvider。
 *
 *
 *
 * {@link ResourceBundle} 工厂模式，通过 {@link ResourceBundle.Control} 实例化出一个资源绑定器。将输入流交给资源绑定器。
 *
 *      File -> InputStream -> Control -> Bundle
 */
@Slf4j
public class LocalTest {
    public static void main(String[] args) throws UnsupportedEncodingException {
        Locale aDefault = Locale.getDefault();
        log.info(aDefault.toString());

        // 读取到中文的 zh_CN,但是编码为ISO-8859-1。得到的是乱码
        ResourceBundle resourceBundle = ResourceBundle.getBundle("i18n.messages");
        String name = resourceBundle.getString("name");
        log.info(name);
        log.info(new String( name.getBytes("ISO-8859-1")));



        // {@link Control} 处理乱码
        ResourceBundle resourceBundle2 = ResourceBundle.getBundle("i18n.messages", new EncodingResourceBundleControl("GBK"));
        String name2 = resourceBundle2.getString("name");
        log.info(name2);




    }


    /**
     * {@since 1.6 } 处理 i18n乱码
     *
     * @see ResourceBundle.Control 处理资源文件的读取和绑定到propertiesResourceBundle 上。
     *
     */
    @Slf4j
    public static final class EncodingResourceBundleControl extends ResourceBundle.Control {

        private final String encoding;

        public EncodingResourceBundleControl(String encoding) {
            this.encoding = encoding;
        }

        @Override
        public ResourceBundle newBundle(String baseName, Locale locale,
                                        String format, ClassLoader loader,
                                        boolean reload) throws IllegalAccessException, InstantiationException, IOException {
            String bundleName = toBundleName(baseName, locale);
            String resourceName = toResourceName(bundleName, "properties");
            URL resourceURL = loader.getResource(resourceName);
            if (resourceURL != null) {
                try {
                    return new PropertyResourceBundle(new InputStreamReader(resourceURL.openStream(), encoding));
                } catch (Exception z) {
                    log.error("",z);
                }
            }
            return super.newBundle(baseName, locale, format, loader, reload);
        }
    }
}
